/*
	scheduler_tables.h

	Contains tables used in the scheduler data area.

	Author: Aidan Goddard 2/7/13
*/
#ifndef SCHEDULER_TABLES_H_INCLUDED
#define SCHEDULER_TABLES_H_INCLUDED

#include "types.h"


////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
/*
	New tables
	24/7/13
*/

// Lock Structure
typedef struct SCH_CLS SCH_CLS;
struct __attribute__((__packed__,aligned(512))) SCH_CLS
{
	uint64_t volatile	ticket[32];
	uint32_t volatile	entering[32];
};


// Process Data Block header (PDB)
typedef struct SCH_PDB SCH_PDB;
struct __attribute__((__packed__,aligned(4096))) SCH_PDB
{
	char volatile		working_directory[1024];
	uint32_t volatile	thread_usage_map[256];
	char volatile		image_name[256];
};

// thread usage map defines
#define THREAD_STATE_INACTIVE 0
#define THREAD_STATE_ACTIVE 1
#define THREAD_STATE_TERMINATING 2
#define THREAD_STATE_SLEEPING 3
#define THREAD_STATE_WAITING 4

// Thread Control Block (TCB)
typedef struct SCH_TCB SCH_TCB;
struct __attribute__((__packed__,aligned(4096))) SCH_TCB
{
	uint8_t volatile	FPU[3072];

	uint64_t volatile	RIP;
	uint64_t volatile	RFLAGS;
	uint64_t volatile	CS;
	uint64_t volatile	DS;
	uint64_t volatile	ES;
	uint64_t volatile	RAX;
	uint64_t volatile	RBX;
	uint64_t volatile	RCX;
	uint64_t volatile	RDX;
	uint64_t volatile	RSI;
	uint64_t volatile	RDI;
	uint64_t volatile	RBP;
	uint64_t volatile	RSP;
	uint64_t volatile	R8;
	uint64_t volatile	R9;
	uint64_t volatile	R10;
	uint64_t volatile	R11;
	uint64_t volatile	R12;
	uint64_t volatile	R13;
	uint64_t volatile	R14;
	uint64_t volatile	R15;

	uint64_t volatile	TID;
	uint64_t volatile	TID_to_wake;
	uint32_t volatile	reserved;
	uint32_t volatile	sleep_counter;

	uint64_t volatile	close_return_value;
	uint64_t volatile	wait_return_value;
};


// Process Control Block (PCB)
typedef struct SCH_PCB SCH_PCB;
struct __attribute__((__packed__,aligned(1024))) SCH_PCB
{
	SCH_CLS				lock;
	char volatile		process_description[256];
	uint64_t volatile	PID;
	uint32_t volatile	state;
	uint32_t volatile	owner_ID;
	uint64_t volatile	PML4;
	SCH_PDB* volatile	PDB;
	SCH_TCB* volatile	TCB;
	void* volatile		resource_table;
	uint32_t volatile	active_threads;
	uint32_t volatile	max_threads_in_TCB;
};


// Scheduler Thread Linked-List Containers
typedef struct SCH_TLC SCH_TLC;
struct __attribute__((__packed__)) SCH_TLC //,aligned(16)
{
	uint16_t volatile	PCB_index;
	uint16_t volatile	TCB_index;
	int32_t	volatile	sleep_offset;
	SCH_TLC* volatile	next_TLC;
};


// Scheduler Data Area (SDA)
// OFFSETS FIXED AS OF 31/7/13

// ********** DO NOT CHANGE OFFSETS FOR 0.4a *******************

typedef struct SCH_SDA SCH_SDA;
struct __attribute__((__packed__)) SCH_SDA
{
	SCH_PCB				PCB[2048];
	SCH_TLC				TLC[8192];
	SCH_TLC* volatile	TLC_stack[8192];
	uint32_t volatile	PCB_stack[2048];

	SCH_CLS				CPU_active_lock[32];
	SCH_CLS				waiting_lock;
	SCH_CLS				sleeping_lock;
	SCH_CLS				TLC_stack_lock;
	SCH_CLS				PCB_stack_lock;
	SCH_CLS				other_lock[28];

	SCH_TLC* volatile	CPU_active_start[32];
	SCH_TLC* volatile	CPU_active_end[32];
	SCH_TLC* volatile	waiting_start;
	SCH_TLC* volatile	waiting_end;
	SCH_TLC* volatile	sleeping_start;
	SCH_TLC* volatile	sleeping_end;

	uint32_t volatile	TLC_stack_index;
	uint32_t volatile	PCB_stack_index;

	uint32_t volatile	scheduling_state;
	uint32_t volatile	active_CPU_count;
	uint32_t volatile	total_process_count;
	uint32_t volatile	total_thread_count;

	SCH_TLC* volatile	CPU_current_thread[32];
	uint32_t volatile	CPU_current_state[32];

	uint32_t volatile	CPU_pc_usage_final[32];
	uint32_t volatile	CPU_pc_usage_timer[32];
	uint32_t volatile	CPU_pc_usage_counter[32];

	uint32_t volatile	CPU_active_thread_count[32];

	uint8_t volatile	reserved[2632];

	SCH_PDB				system_PDB[16];
	SCH_TCB				system_TCB[32];

	uint8_t				system_monitor_stack[8192];
	uint8_t				system_cleanup_stack[8192];
	uint8_t		 		system_setup_stack[8192];
	uint8_t				system_idle_stack[4096];

	uint32_t volatile	CPU_selection_start;

};

#define SCHEDULING_STATE_ENABLED 1
#define SCHEDULING_STATE_DISABLED 0
#define CPU_SCHEDULING 1
#define CPU_NOT_SCHEDULING 0

#define PROCESS_STATE_UNUSED 0
#define PROCESS_STATE_ACTIVE 1
#define PROCESS_STATE_TERMINATING 2
#define PROCESS_STATE_TERMINATED 3

// global pointer to Scheduler Data Area
static SCH_SDA* SCHEDULER = (SCH_SDA*)(KOFFSET + 0xb00000);

// global pointer to PDBs
static SCH_PDB* DATABLOCKS = (SCH_PDB*)(KOFFSET + 0x2600000);








#endif
